#include "Enesim.h"
#include <math.h>

typedef struct _Button02
{
	struct {
		Enesim_Renderer *background;
		Enesim_Renderer *rectangle;
	} shape;
	struct {
		Enesim_Renderer *pattern;
		Enesim_Renderer *shade;
		Enesim_Renderer *text;
	} background;
	Enesim_Color light;
	Enesim_Color dark;
	Enesim_Renderer_Sw_Fill fill;
} Button02;

static void _draw(Enesim_Renderer *r, int x, int y, unsigned int len, uint32_t *dst)
{
	Button02 *button;

	button = enesim_renderer_data_get(r);
	button->fill(button->shape.rectangle, x, y, len, dst);
}

static Eina_Bool _setup(Enesim_Renderer *r, Enesim_Renderer_Sw_Fill *fill)
{
	Button02 *button;
	Enesim_Matrix matrix;
	double ox, oy;

	button = enesim_renderer_data_get(r);
	/* the matrix */
	enesim_renderer_transformation_get(r, &matrix);
	enesim_renderer_transformation_set(button->shape.rectangle, &matrix);
	/* the origin */
	enesim_renderer_origin_get(r, &ox, &oy);
	enesim_renderer_origin_set(button->shape.rectangle, ox, oy);

	if (!enesim_renderer_sw_setup(button->shape.rectangle)) return EINA_FALSE;
	button->fill = enesim_renderer_sw_fill_get(button->shape.rectangle);
	if (!button->fill) return EINA_FALSE;

	*fill = _draw;

	return EINA_TRUE;
}

static void _cleanup(Enesim_Renderer *r)
{
	Button02 *button;

	button = enesim_renderer_data_get(r);
	enesim_renderer_sw_cleanup(button->shape.rectangle);
}

static void _free(Enesim_Renderer *r)
{
	Button02 *button;

	button = enesim_renderer_data_get(r);
	if (button->shape.background)
		enesim_renderer_unref(button->shape.background);
	if (button->shape.rectangle)
		enesim_renderer_unref(button->shape.rectangle);
}

static Enesim_Renderer_Descriptor _descriptor = {
	.sw_setup = _setup,
	.sw_cleanup = _cleanup,
	.free = _free,
};

void fancy_button02_light_color_set(Enesim_Renderer *r, Enesim_Color color)
{
	Enesim_Renderer *r1;
	Button02 *button;

	button = enesim_renderer_data_get(r);
	r1 = button->background.pattern;
	enesim_renderer_stripes_even_color_set(r1, color);

	r1 = button->shape.rectangle;
	enesim_renderer_shape_outline_color_set(r1, color);
}

void fancy_button02_dark_color_set(Enesim_Renderer *r, Enesim_Color color)
{
	Enesim_Renderer *r1;
	Button02 *button;

	button = enesim_renderer_data_get(r);
	r1 = button->background.pattern;
	enesim_renderer_stripes_odd_color_set(r1, color);
}

Enesim_Renderer * fancy_button02_new(void)
{
	Enesim_Renderer *thiz, *r;
	Button02 *button;

	button = calloc(1, sizeof(Button02));
	if (!button) return NULL;

	r = enesim_renderer_stripes_new();
	if (!r) goto shape_background_err;
	enesim_renderer_stripes_even_color_set(r, 0xffa1ff38);
	enesim_renderer_stripes_odd_color_set(r, 0xffb3ff00);
	enesim_renderer_stripes_even_thickness_set(r, 3);
	enesim_renderer_stripes_odd_thickness_set(r, 5);
	button->background.pattern = r;

	r = enesim_renderer_stripes_new();
	//if (!r) goto shape_background_err;
	enesim_renderer_stripes_even_color_set(r, 0);
	enesim_renderer_stripes_odd_color_set(r, 0x33000000);
	enesim_renderer_stripes_even_thickness_set(r, 1);
	enesim_renderer_stripes_odd_thickness_set(r, 1);
	button->background.shade = r;

	r = enesim_text_new();
	enesim_text_width_set(r, 12);
	enesim_text_height_set(r, 12);
	button->background.text = r;
	enesim_renderer_origin_set(button->background.text, 0, 25);
	enesim_renderer_color_set(button->background.text, 0xff000000);

	r = enesim_renderer_compound_new();
	//if (!r) goto shape_compound_err;
	enesim_renderer_compound_layer_add(r, button->background.pattern, ENESIM_FILL);
	enesim_renderer_compound_layer_add(r, button->background.shade, ENESIM_BLEND);
	enesim_renderer_compound_layer_add(r, button->background.text, ENESIM_BLEND);
	button->shape.background = r;

	r = enesim_renderer_rectangle_new();
	if (!r) goto shape_rectangle_err;
	enesim_renderer_rectangle_corners_set(r, EINA_TRUE, EINA_TRUE, EINA_TRUE, EINA_TRUE);
	enesim_renderer_rectangle_corner_radius_set(r, 5);
	enesim_renderer_shape_outline_weight_set(r, 2);
	enesim_renderer_shape_outline_color_set(r, 0xffa1ff38);
	enesim_renderer_shape_fill_renderer_set(r, button->shape.background);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_SHAPE_DRAW_MODE_STROKE_FILL);
	button->shape.rectangle = r;

	thiz = enesim_renderer_new(&_descriptor, button);
	if (!thiz) goto renderer_err;

	return thiz;

renderer_err:
	enesim_renderer_unref(button->shape.rectangle);
shape_rectangle_err:
	enesim_renderer_unref(button->shape.background);
shape_background_err:
	free(button);
	return NULL;
}

static void _button02_update_size(Button02 *button, unsigned int width, unsigned int height)
{
	Enesim_Matrix t;
	float sa, ca;

	sa = sin(-40 * M_PI / 180.0);
	ca = cos(-40 * M_PI / 180.0);
	t.xx = ca;               t.xy = sa;               t.xz = 0;
	t.yx = -sa / 2;    t.yy = ca / 2;     t.yz = 0;
	t.zx = 0;                t.zy = 0;                t.zz = 1;
	enesim_renderer_transformation_set(button->background.pattern, &t);

	enesim_renderer_stripes_even_thickness_set(button->background.shade, height / 4.0);
	enesim_renderer_stripes_odd_thickness_set(button->background.shade, height / 4.0);
	t.xx = 1;               t.xy = 0;                t.xz = 0;
	t.yx = 0;               t.yy = 0.5;              t.yz = 0;
	t.zx = 0;               t.zy = 0;                t.zz = 1;
	enesim_renderer_transformation_set(button->background.shade, &t);

	enesim_renderer_origin_set(button->background.text, 0, height/2 + 6);
}

void fancy_button02_width_set(Enesim_Renderer *r, unsigned int width)
{
	Button02 *button;
	unsigned int height;

	button = enesim_renderer_data_get(r);
	enesim_renderer_rectangle_width_set(button->shape.rectangle, width);
	height = enesim_renderer_rectangle_height_get(button->shape.rectangle);
	_button02_update_size(button, width, height);
}

void fancy_button02_height_set(Enesim_Renderer *r, unsigned int height)
{
	Button02 *button;
	unsigned int width;

	button = enesim_renderer_data_get(r);
	enesim_renderer_rectangle_height_set(button->shape.rectangle, height);
	width = enesim_renderer_rectangle_width_get(button->shape.rectangle);
	_button02_update_size(button, width, height);
}

void fancy_button02_text_set(Enesim_Renderer *r, char *string)
{
	Button02 *button;

	button = enesim_renderer_data_get(r);
	enesim_text_text_set(button->background.text, string);
}
